package Table;

use strict;
use @@PACKAGE@@::WebAPI::Util;

sub new {

    # Get the class name
    my $stInvocant = shift @_;
    my $stClass = ref($stInvocant) || $stInvocant;

    # Create the current instance and bless into class
    my $rSelf = { };
    bless($rSelf,$stClass);

    # All arguments are treated as the table attr
    # default attr are driven by the display (i.e., browser)
    my %hTableAttr = ( @_ );
    $rSelf->{table_attr} = \%hTableAttr;

    # Now set all default values for new table 
    $rSelf->{rows} = 0;
    $rSelf->{cols} = 0;
    $rSelf->{row_attr} = [];
    $rSelf->{cell_content} = [];
    $rSelf->{cell_attr} = [];

    return $rSelf;
}

sub setRowAttr {

    my $rSelf = shift(@_);
    my $iRow = shift(@_);

    # Remaining arguments are considered row attributes
    my %hAttr = ( @_ );

    # declare boolean result
    my $boResult = 1;

    if ($iRow >= 0) {
	$rSelf->{row_attr}->[$iRow] = \%hAttr;
    } else {
	$boResult = 0;
    }

    return $boResult;
}

sub addChild {

    # First argument is the object
    # Then the xPos, yPos, object, ...
    my $rSelf = shift(@_);
    my $iRow = shift(@_);
    my $iCol = shift(@_);
    my $rObject = shift(@_) || "";

    # Remaining arguments are considered property name/value pairs
    my %hAttr = ( @_ );

    # declare boolean result
    my $boResult = 1;

    # Now, set the information at these coordinates
    if ($iCol >=0 && $iRow >= 0) {

	if ($iRow+1 > $rSelf->{rows}) { $rSelf->{rows} = $iRow+1; }
	if ($iCol+2 > $rSelf->{cols}) { $rSelf->{cols} = $iCol+1; }
	
	$rSelf->{cell_content}->[$iRow][$iCol] = $rObject;
	$rSelf->{cell_attr}->[$iRow][$iCol] = \%hAttr; # Cast to scalar reference
	
    } else {

	$boResult = 0;
    }

    return $boResult;
}

sub draw {

    # There are no arguments to the draw method (too late!)
    my $rSelf = shift @_;

    # Create table header, etc
    my $stResult = "<table cols='$rSelf->{cols}'";
    
    $stResult .= Util::get_attr_str($rSelf->{table_attr}) .">\n";

    my $iRow;

    for $iRow ( 0 .. $rSelf->{rows}-1 ) {

	$stResult .= $rSelf->draw_row($iRow);
    }
    
    $stResult .= "</table>\n";

    return $stResult;
}

sub draw_row {

    my $rSelf = shift @_;
    my $iRow = shift @_;
    my $stResult = "\t<tr".Util::get_attr_str($rSelf->{row_attr}->[$iRow]).">\n";
    
    my $iCol;
    for $iCol ( 0 .. $rSelf->{cols}-1 ) {
	
	$stResult .= $rSelf->draw_cell($iRow,$iCol);
    }
    
    $stResult .= "\t</tr>\n";
    
    return $stResult;
}

sub draw_cell {

    my $rSelf = shift @_;
    my $iRow = shift @_;
    my $iCol = shift @_;
    my $stResult = "";

    # Now create content
    my $rContent = $rSelf->{cell_content};
    my @arContent = @$rContent;
    
    my $rAttr = $rSelf->{cell_attr};
    my @arAttr = @$rAttr;
    
    if ( defined( $arAttr[$iRow][$iCol] ) || defined( $arContent[$iRow][$iCol] ) ) {
		
	$stResult .= "\t\t<td".Util::get_attr_str($arAttr[$iRow][$iCol]).">";
	
	if ( defined( $arContent[$iRow][$iCol] ) ) {

	    $stResult .=
		ref($arContent[$iRow][$iCol]) ? 
		$arContent[$iRow][$iCol]->draw() :
		$arContent[$iRow][$iCol];	

	} 
	
	$stResult .= "</td>\n";
    }
    
}

1;
